package com.snap.awesomeserial.model;

import android.content.Context;
import android.os.Environment;
import android.support.annotation.NonNull;

import com.snap.awesomeserial.AppConfig;
import com.snap.awesomeserial.bean.SettingInfo;
import com.snap.awesomeserial.utils.FileUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ConfigManager {

    public final static String soFileName = "libserial_port.so";

    private static ConfigManager sInstance = new ConfigManager();
    private SettingInfo mInfo;
    private ExecutorService singlePool = Executors.newSingleThreadExecutor();
    private String path;

    private ConfigManager() {
    }

    public static ConfigManager getInstance() {
        return sInstance;
    }

    /**
     * 初始化 配置路径 异步加载配置到内存中
     */
    public void init(Context context) {
        //把asset目录下的so文件复制到  app内存files目录下，以备loadLibrary加载so失败时，加载这儿的so文件
        singlePool.execute(() -> {
            try {
                File soFile = new File(context.getFilesDir(), soFileName);
                InputStream is = context.getAssets().open(soFileName);
                FileUtils.copyInputStreamToFile(is, soFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        path = Environment.getExternalStorageDirectory().getPath()
                + AppConfig.ROOT_DIRECTORY + "sys.config";
        singlePool.execute(this::loadConfig);
    }

    /**
     * 设置页面 调用此处获取 配置的各项值
     * 通常：对这个对象调用setter方法后，紧跟着调用{@link #update()}
     */
    @NonNull
    public SettingInfo getSettingInfo() {
        return mInfo;
    }

    /**
     * 外部调用这个方法来更新文件
     */
    public void update() {
        singlePool.execute(this::saveConfig);
    }

    private void loadConfig() {
        File file = new File(path);
        if (file.exists()) {
            byte[] byteArray = FileUtils.readFile(file);
            if (byteArray != null) {
                mInfo = FileUtils.deserialize(byteArray, SettingInfo.class);
            }
        }

        if (mInfo == null) {
            mInfo = generateDefaultConfig();
            saveConfig();
        }
    }

    /**
     * 存储config文件
     */
    private void saveConfig() {
        byte[] byteArray = FileUtils.serialize(mInfo);
        File file = new File(path);
        FileUtils.writeFile(file, byteArray);
    }

    /**
     * 生成默认的设置文件
     */
    private SettingInfo generateDefaultConfig() {
        SettingInfo info = new SettingInfo();
        info.setEnvLimitTemp(AppConfig.DEF_ENV_TEMP);
        return info;
    }
}
